package com.example.sikong.service;

import com.alibaba.fastjson.JSON;
import com.example.common.RedisKeyName;
import com.example.sikong.dto.*;
import com.example.sikong.feign.SiKongApiClient;
import com.example.util.CreateLiveUrl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Slf4j
@Service
public class SiKongApiClientService {

    @Autowired
    private SiKongApiClient siKongApiClient;

    @Autowired
    private RedisProvider redisProvider;
    @Autowired
    private SiKongSyncService syncService;
    @Autowired
    private HangarService hangarService;

    protected final String isDroneKey = "isDrone";


    public Map<String, Object> multipleStartHangarDeviceLive(Set<String> sns) {
        Map<String, Object> result = new HashMap<>();
        for (String sn : sns) {
            try {
                Map<String, String> map = startHangarDeviceLive(sn);
                result.put(sn, map);
            } catch (Exception e) {
                log.error("开启直播失败", e);
            }
        }
        return result;
    }

    public Map<String, String> startHangarDeviceLive(String sn) {
        Map<String, Object> bySn = getDJHangarConfigBySn(sn);
        if (bySn.isEmpty()) {
            throw new RuntimeException("未知设备不能开启直播");
        }
        boolean isDrone = (boolean) bySn.get(isDroneKey);
        // 设备是否在线
        DJHangarConfigDTO copy = JSON.parseObject(JSON.toJSONString(bySn), DJHangarConfigDTO.class);
        SiKongStartLiveDTO params = new SiKongStartLiveDTO();
        params.setRtmp_url(copy.getRtmpUrl());
        params.setConverter_name(System.currentTimeMillis() + "");
        params.setSn(sn);
        // 以下两个飞机的需要覆盖
        params.setCamera(copy.getCamera());
        params.setVideo(copy.getVideo());
        if (isDrone) {
            //  设备不在线报错
            Object onLiveDrone = redisProvider.get(RedisKeyName.SI_KONG_OSD_DRONE_ONLINE + ":" + sn);
            if (onLiveDrone == null) {
                throw new RuntimeException("设备不在线");
            }
            // 如果时无人机,从redis 获取
            List<Map<String, Object>> cameraList = (List<Map<String, Object>>) redisProvider.get(RedisKeyName.SI_KONG_OSD_LIVE_CAPACITY_CAMERA_LIST + ":" + sn);
            String videoId = getVideoId(cameraList);
            if ("".equals(videoId)) {
                throw new RuntimeException("无可用摄像头");
            }
            String[] split = videoId.split("/");
            params.setCamera(split[0]);
            params.setVideo(split[1]);
        }
        Map<String, String> map = null;
        Set<String> allKeys = redisProvider.getAllKeys(RedisKeyName.SI_KONG_SN_CACHE + ":" + params.getSn() + ":*");
        if (allKeys != null && !allKeys.isEmpty()) {
            for (String allKey : allKeys) {
                redisProvider.get(allKey);
                map = (Map<String, String>) redisProvider.get(allKey);
                if (map != null) {
                    return map;
                }
            }
        }

        // 如果不在线  开启码流
        SiKongResult<LiveStartResultDTO> liveStartResultDTOSiKongResult = null;
        try {
            liveStartResultDTOSiKongResult = siKongApiClient.startLive(copy.getOrgSecret(), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        syncService.refreshInLive(copy.getOrgSecret(), params.getSn(), params.getCamera());
        map = CreateLiveUrl.general_pull_url(copy.getPullDomain(), copy.getPullKey(), copy.getAppName(), String.join("_", sn, params.getCamera()), copy.getActiveTime());
        map.put("converterId", "");

        if (liveStartResultDTOSiKongResult != null && liveStartResultDTOSiKongResult.getCode() == 0) {
            LiveStartResultDTO data = liveStartResultDTOSiKongResult.getData();
            if (data != null) {
                LiveStartResultDTO.LiveStartDTO liveStartDTO = data.getData();
                String converterId = liveStartDTO.getConverter_id();
                map.put("converterId", converterId);

                //缓存直播信息
                redisProvider.set(RedisKeyName.SI_KONG_SN_CACHE + ":" + params.getSn() + ":" + converterId, map, 3600);
            }
        }
        return map;
    }

    private String getVideoId(List<Map<String, Object>> cameraList) {
        cameraList = new ArrayList<>(cameraList);
        cameraList.sort((o1, o2) -> {
            String cameraIndex1 = (String) o1.get("camera_index");
            String cameraIndex2 = (String) o2.get("camera_index");
            String[] split1 = cameraIndex1.split("-");
            String[] split2 = cameraIndex2.split("-");
            int i1 = Integer.parseInt(split1[0]);
            int i2 = Integer.parseInt(split2[0]);
            if (i1 != i2) {
                return i1 - i2;
            }
            i1 = Integer.parseInt(split1[1]);
            i2 = Integer.parseInt(split2[1]);
            if (i1 != i2) {
                return i1 - i2;
            }
            i1 = Integer.parseInt(split1[2]);
            i2 = Integer.parseInt(split2[2]);
            return i1 - i2;
        });
        for (Map<String, Object> map : cameraList) {
            List<Map<String, Object>> videoList = (List<Map<String, Object>>) map.get("video_list");
            String cameraIndex = (String) map.get("camera_index");
            for (Map<String, Object> stringObjectMap : videoList) {
                String videoType = (String) stringObjectMap.get("video_type");
                if ("zoom".equals(videoType)) {
                    return cameraIndex + "/" + stringObjectMap.get("video_index");
                }
            }
        }

        // 没有找到使用排序后的第一个
        Map<String, Object> map = cameraList.get(0);
        List<Map<String, Object>> videoList = (List<Map<String, Object>>) map.get("video_list");
        if (CollectionUtils.isEmpty(videoList)) {
            return "";
        }
        String cameraIndex = (String) map.get("camera_index");
        Object videoIndex = videoList.get(0).get("video_index");
        return cameraIndex + "/" + videoIndex;
    }

    protected Map<String, Object> getDJHangarConfigBySn(String sn) {
        HangarDTO bySn = hangarService.findByHangarSn(sn);
        if (bySn == null) {
            Object o = redisProvider.get(RedisKeyName.SI_KONG_BINDING + ":" + sn);
            if (o == null) {
                return Collections.emptyMap();
            }
            bySn = hangarService.findByHangarSn(o.toString());
            if (bySn == null) {
                return Collections.emptyMap();
            }
            Map<String, Object> config = bySn.getConfig();
            config.put(isDroneKey, true);
            return config;
        } else {
            Map<String, Object> config = bySn.getConfig();
            config.put(isDroneKey, false);
            return config;
        }
    }

    /**
     * 关闭所有 sn 的直播
     */
    public boolean stopLiveByInLiveKey(String sn) {
        boolean flag = false;
        Set<String> keys = redisProvider.getAllKeys(RedisKeyName.SI_KONG_IN_LIVE + ":" + sn + ":*");
        if (CollectionUtils.isEmpty(keys)) {
            return flag;
        }
        Set<String> channels = new HashSet<>();
        for (String key : keys) {
            try {
                LiveContainerResultDTO.ContainerDTO member = (LiveContainerResultDTO.ContainerDTO) redisProvider.get(key);
                SiKongResult<Object> objectSiKongResult = siKongApiClient.stopLive(member.getOrgSecret(), member.getConverter_id());
                if (objectSiKongResult.success()) {
                    redisProvider.del(key);
                    channels.add(RedisKeyName.SI_KONG_LIVE_SUCCESS + ":" + member.getRtc_channel());
                }
            } catch (Exception e) {
                log.error("关闭直播{}时出错", key, e);
            }
        }
        if (!CollectionUtils.isEmpty(channels)) {
            redisProvider.del(channels.toArray(new String[0]));
        }
        flag = true;
        return flag;
    }

    public boolean stopLiveByInLiveKey(String sn, String converterId) {
        redisProvider.del(converterId);

        boolean flag = false;
        Set<String> keys = redisProvider.getAllKeys(RedisKeyName.SI_KONG_IN_LIVE + ":" + sn + ":*");
        if (CollectionUtils.isEmpty(keys)) {
            return flag;
        }
        Set<String> channels = new HashSet<>();
        for (String key : keys) {
            try {
                if (key.contains(converterId)) {
                    LiveContainerResultDTO.ContainerDTO member = (LiveContainerResultDTO.ContainerDTO) redisProvider.get(key);
                    SiKongResult<Object> objectSiKongResult = siKongApiClient.stopLive(member.getOrgSecret(), member.getConverter_id());
                    if (objectSiKongResult.success()) {
                        redisProvider.del(key);

                        //删除sn缓存
                        redisProvider.del(RedisKeyName.SI_KONG_SN_CACHE + ":" + sn + ":" + converterId);
                        channels.add(RedisKeyName.SI_KONG_LIVE_SUCCESS + ":" + member.getRtc_channel());
                    }
                }

            } catch (Exception e) {
                log.error("关闭直播{}时出错", key, e);
            }
        }
        if (!CollectionUtils.isEmpty(channels)) {
            redisProvider.del(channels.toArray(new String[0]));
        }
        flag = true;
        return flag;
    }

}
